package com.iee.guava.collections;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.Map;

/**
 * 统计业务实现示例
 * HashBasedTable的用处就是将我们的数据结构封装成类似于excel表格，有自己的行和列，我们把学生每个科目的成绩放在同一行，
 * 同一个科目的成绩放在同一列，使用提供的rowMap(),columnMap()的api帮助我们快速提出行或列的数据，然后进行计算处理
 */
public class HashBasedTableDemo {

    /**
     * 使用假数据进行测试 真是场景 testScoreList通过执行上面sql获得
     */
    public static void main(String[] args) {
        TestScore t1 = new TestScore("张三", "语文", "三年二班", 80D, "2021上");
        TestScore t2 = new TestScore("张三", "数学", "三年二班", 80D, "2021上");
        TestScore t3 = new TestScore("李四", "语文", "三年二班", 100D, "2021上");
        TestScore t4 = new TestScore("李四", "数学", "三年二班", 90D, "2021上");
        ArrayList<TestScore> testScoreList = Lists.newArrayList(t1, t2, t3, t4);
        // 2.初始化HashBasedTable HashBasedTable<R, C, V> R相当行 就是学生姓名 C 相当于列 就是科目
        HashBasedTable<String, String, Double> table = HashBasedTable.create();
        for (TestScore testScore : testScoreList) {
            table.put(testScore.getStudentName(), testScore.getSubject(), testScore.getScore());
        }
        //3.计算每个学生的总分
        Map<String, Map<String, Double>> studentSubjectScoreMap = table.rowMap();
        Map<String, Double> studentGrossScoreMap = Maps.newHashMap();
        for (Map.Entry<String, Map<String, Double>> entry : studentSubjectScoreMap.entrySet()) {
            String studentName = entry.getKey();
            // 总分
            double grossScore = entry.getValue().values().stream().mapToDouble(e -> e).sum();
            studentGrossScoreMap.put(studentName, grossScore);
        }
        // 4.计算班级总分平均分
        double grossScoreAvg = studentGrossScoreMap.values().stream().mapToDouble(e -> e).average().orElse(-1);
        // 5.计算科目平均分
        Map<String, Map<String, Double>> subjectStudentScoreMap = table.columnMap();
        Map<Object, Object> subjectScoreAvgMap = Maps.newHashMap();
        for (Map.Entry<String, Map<String, Double>> entry : subjectStudentScoreMap.entrySet()) {
            String subject = entry.getKey();
            // 科目平均分
            double subjectScoreAvg = entry.getValue().values().stream().mapToDouble(e -> e).average().orElse(-1);
            subjectScoreAvgMap.put(subject, subjectScoreAvg);
        }
        // 学生总分
        System.out.println(studentGrossScoreMap);
        // 班级科目平均分
        System.out.println(subjectScoreAvgMap);
        // 班级总分平均分
        System.out.println(grossScoreAvg);
    }
}


/**
 * 学生科目成绩实体
 */
@Data
@AllArgsConstructor
class TestScore {
    private String studentName;

    private String subject;

    private String semester;

    private Double score;

    private String classGrade;

    // 省略get set toString ...
}
